# 01 C++强转的区别 ## 1.1 reinterpret_cast 1. 任意类型的指针之间的相互转换 2. 任意引用之间的相互转换 - int& ↔ double& ↔ char& - int*↔ double* ↔ char*↔ void* - 例:`int*ptr = reinterpret_cast(&d)`; - 例:`int& ref = reinterpret_cast(a)`; 3. 指针 ↔ 整数之间的转换 - 指针 → 整数:uintptr_t / intptr_t - 整数 → 指针:同上 - 整数类型必须是 uintptr_t 或 intptr_t(保证长度相等) - 例:`uintptr_t addr = reinterpret_cast(ptr)`; 核心原理: - 不修改内存内容 - 只改变对内存的类型解释 - 按位重新解读 不允许的转换: - 值类型之间的转换(用 static_cast) - 删除 const(用 const_cast) ## 1.2 static_cast **数据转换:** 一般是基础整数和浮点数之间的相互转换; 1. 编译时数据的类型发生转换,如果存在可能溢出截断,不会发出告警和错误。 2. 运行阶段,会读取源数据内存,由cpu指令进行转换, 可能发生溢出和截断,也不会发出告警和错误。 **指针转换:** 继承体系的指针转换或者`void *`和普通指针之间的转换; 1. 具体向抽象转换:子类转换成为基类(向上转换),或者转换成void*(类型擦除), 是安全的; 2. 抽象向具体转换:基类指针转换成为子类指针(向下转换),或者void*转换成为某个类型的指针(类型擦除后恢复);可能存在安全隐患,需要开发人员确保指针指向的内容和目标类型一致。 **使用场合:** 1. 架构设计与兼容:如工厂函数接口封装、类型擦除(Type Erasure)、兼容 C 风格底层 API,利用 void* 或基类指针抹平类型差异。 2. 极致性能优化:规避动态多态(虚函数表查找、RTTI 运行期检查)带来的性能损耗与内存膨胀(vptr),满足高频执行代码、游戏引擎、AI 推理框架等对零开销(Zero-overhead)的严苛要求。 ## 1.3 dynamic_cast dynamic_cast 必须在运行阶段借助 RTTI(Run-Time Type Information,运行阶段类型识别)机制现场进行类型校验。 只能用于多态类型(即类中必须包含至少一个虚函数,否则编译报错)。 向上转换: 子类 →基类,完全安全,隐式转换即可,显式使用较少; 向下转换: 基类->子类, 常用于判断基类数据是否是某个子类; 注意如果是指针转换失败,返回nullptr; 如果是引用转换是被,抛出\的std::bad_cast错误; ## 1.4 const_cast 1. 移除 const 属性标记 - 作用对象:指针和引用 - 主要场景:调用第三方库或 C 语言接口 - 原因:这些接口设计不规范,入参没有 const 限定 - 前提:确保原数据确实是可修改的(不是真正的 const 对象) - 重要:不能用来修改真正的 const 对象(未定义行为) 2. 统一接口实现逻辑 - 应用场景:类中 const 和 non-const 版本的接口 - 做法:让 non-const 版本转发到 const 版本 - 目的:避免代码重复,保证逻辑一致性 - 最佳实践:const 版本写真实逻辑,non-const 版本只负责转发 额外注意: - const_cast 是四大强制转换中最危险的 - 使用前务必确认原数据的真实可修改性 - 应避免过度使用,优先考虑 mutable 关键字